# -*- coding: utf-8 -*-
#
# Copyright (C) 2011  Benjamin Heil
#
# This file is part of Feedmail.
#
# Feedmail is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from django import forms
from django.core.urlresolvers import reverse
from django.core.mail import mail_managers
from django.conf import settings
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import cache_control
from django.template import RequestContext
from account.forms import register_form, profile_form, delete_my_account_form, resend_activation_mail_form
from account.models import AccountActivation, AccountProfile

def _set_user_active_and_validated(user):
    user.is_active = True
    user.save()
    profile = AccountProfile.objects.get(user=user)
    profile.mail_validated = True
    profile.save()
    if settings.SEND_REGISTER_STATUS_EMAILS:
        mail_managers(u'User wurde aktiviert',
                      u'Der User wurde aktiviert: \n\nName: %s\nMail: %s\nID: %s' % \
                      (user.username, user.email, user.id))

def _generate_activation_id(user, only_mail_change):
    # Generate new activation id for this user and send mail
    act = AccountActivation()
    act.user = user
    act.only_mail_change = only_mail_change
    act.save()
    act.send_activation_mail()

def activate(request, activation_id):
    state = -1
    try:
        u = AccountActivation.objects.get(activation_id=activation_id, only_mail_change=False)
    except AccountActivation.DoesNotExist:
        u = None
    if u is not None:
        if u.is_activation_in_time():
            state = 0
            _set_user_active_and_validated(u.user)
        u.delete()
    return render_to_response('account/activation.html', {'state': state},
                              context_instance=RequestContext(request))

def resend_activation_mail(request):
    if not request.user.is_anonymous():
        _generate_activation_id(request.user, False)
        msg = u'Es wurde eine neue Aktivierungsmail an %s verschickt. Bitte rufe Deine Mails ab!' % (request.user.email)
        return render_to_response('account/resend_activation_mail.html', {'msg': msg},
                                  context_instance=RequestContext(request))
    else:
        if request.method == 'POST':
            form = resend_activation_mail_form(request.POST)
            if form.is_valid():
                email = form.cleaned_data['email']
                try:
                    user = User.objects.get(email=email)
                    _generate_activation_id(user, False)
                    msg = u'Es wurde eine neue Aktivierungsmail an %s verschickt. Bitte rufe Deine Mails ab!' % (email)
                except User.DoesNotExist:
                    msg = u'Diese Mail-Adresse ist nicht registriert. Du kannst damit aber einen <a href="%s">neuen Account anlegen</a>!' % (reverse('account_register'))
                return render_to_response('account/resend_activation_mail.html', {'msg': msg},
                                          context_instance=RequestContext(request))
        else:
            form = resend_activation_mail_form()
        return render_to_response('account/resend_activation_mail.html', {'form': form},
                                  context_instance=RequestContext(request))

def mail_confirmation(request, activation_id):
    state = -1
    try:
        u = AccountActivation.objects.get(activation_id=activation_id, only_mail_change=True)
    except AccountActivation.DoesNotExist:
        u = None
    if u is not None:
        if u.is_activation_in_time():
            state = 0
            _set_user_active_and_validated(u.user)
        u.delete()
    return render_to_response('account/mail_confirmation.html', {'state': state},
                              context_instance=RequestContext(request))

@cache_control(private=True)
def register(request):
    if request.method == 'POST':
        form = register_form(request.POST)
        if form.is_valid():
            u = form.save()
            _generate_activation_id(u, False)
            if settings.SEND_REGISTER_STATUS_EMAILS:
                mail_managers(u'Neue User-Registrierung',
                              u'Ein neuer User hat sich gerade auf %s registriert:\n\nName: %s\nMail: %s\nID: %s' % \
                              (settings.SITE_TITLE, u.username, u.email, u.id))
            return render_to_response('account/registered.html',
                                      context_instance=RequestContext(request))
    else:
        form = register_form()
    return render_to_response('account/register.html', {'form': form},
                              context_instance=RequestContext(request))

@login_required
@cache_control(private=True)
def profile(request):
    profile = request.user.get_profile()
    if request.method == 'POST':
        form = profile_form(request.POST)
        if form.is_valid():
            user = User.objects.get(username=request.user.username)
            msg = "Deine Daten wurden geändert!"
            try:
                if form.cleaned_data['username'] != user.username:
                    try:
                        User.objects.get(username=form.cleaned_data['username'])
                        msg = "Dieser Benutzername ist schon vergeben!"
                        raise forms.ValidationError(msg)
                    except User.DoesNotExist:
                        pass
                if form.cleaned_data['email'] != user.email:
                    try:
                        User.objects.get(email=form.cleaned_data['email'])
                        msg = "Diese Mail-Adresse wird schon verwendet!"
                        raise forms.ValidationError(msg)
                    except User.DoesNotExist:
                        pass
                    user.email = form.cleaned_data['email']
                    user.save()
                    #user.is_active = False
                    _generate_activation_id(user, True)
                    msg = "Dir wurde eine Mail mit einem Aktivierungslink zugeschickt. Bitte rufe diesen Link auf, um die Änderung abzuschließen."
            except forms.ValidationError:
                pass
            else:
                form.save(user)
            return render_to_response('account/profile.html', {'msg': msg},
                                      context_instance=RequestContext(request))
    else:
        data = {
            'username': request.user.username,
            'email': request.user.email,
        }
        form = profile_form(data)
    return render_to_response('account/profile.html',
                              {'form': form,
                               'del_own_acc': settings.ACCOUNT_CAN_DELETE},
                              context_instance=RequestContext(request))

@login_required
def delete_my_account(request):
    if not settings.ACCOUNT_CAN_DELETE:
        return HttpResponseRedirect(reverse('account_profile'))
    if request.method == 'POST':
        form = delete_my_account_form(request.POST)
        if form.is_valid():
            if form.cleaned_data['confirmation']:
                username = request.user.username
                user = User.objects.get(username=username)
                profile = AccountProfile.objects.get(user=user)
                # TODO: dispatcher checken
                # TODO: Abos entfernen, wenn der User gelöscht wird
                #dispatcher.send(signal=account_signals.account_pre_delete, user=user)
                auth.logout(request)
                profile.delete()
                user.delete()
                #dispatcher.send(signal=account_signals.account_post_delete, user=user)
                msg = u"Dein Account wurde gelöscht!"
                if settings.SEND_REGISTER_STATUS_EMAILS:
                    mail_managers(u'Account gelöscht',
                                  u'Der User %s hat seinen Account gelöscht!' % username)
            else:
                msg = u"Du musst das Löschen explizit bestätigen, indem Du die Box aktivierst!"
            return render_to_response('account/delete.html', {'msg': msg},
                                      context_instance=RequestContext(request))
    else:
        form = delete_my_account_form()
    return render_to_response('account/delete.html', {'form': form},
                              context_instance=RequestContext(request))
